#include "main.hpp"

bool Pickable::pick(Actor *owner, Actor *wearer) {
	if ( wearer->container && wearer->container->add(owner) ) {
		engine.actors.remove(owner);
		return true;
	}
	return false;
}

void Pickable::drop(Actor *owner, Actor *wearer) {
	if ( wearer->container ) {
		wearer->container->remove(owner);
		engine.actors.push(owner);
		owner->x=wearer->x;
		owner->y=wearer->y;
		engine.gui->message(TCODColor::lightGrey,"%s drops a %s.",
			wearer->name,owner->name);
	}
}

bool Pickable::use(Actor *owner, Actor *wearer) {
	if ( wearer->container ) {
		wearer->container->remove(owner);
		delete owner;
		return true;
	}
	return false;
}

Healer::Healer(float amount) : amount(amount) {
}

bool Healer::use(Actor *owner, Actor *wearer) {
	if ( wearer->destructible ) {
		float amountHealed = wearer->destructible->heal(amount);
		if ( amountHealed > 0 ) {
			return Pickable::use(owner,wearer);
		}
	}
	return false;
}

StaticBolt::StaticBolt(float range, float damage) 
	: range(range),damage(damage) {
}

bool StaticBolt::use(Actor *owner, Actor *wearer) {
	Actor *closestMonster=engine.getClosestMonster(wearer->x,wearer->y,range);
	if (! closestMonster ) {
		engine.gui->message(TCODColor::lightGrey,"There is no enemy in range.");
		return false;
	}
	// hit closest monster for <damage> hit points
	engine.gui->message(TCODColor::lightBlue,
		"You discharge into the %s with a bright flash!\n"
		"You hit for %g damage.",
		closestMonster->name,damage);
	closestMonster->destructible->takeDamage(closestMonster,damage);
	return Pickable::use(owner,wearer);
}

Confuser::Confuser(int nbTurns, float range)
	: nbTurns(nbTurns), range(range) {
}

bool Confuser::use(Actor *owner, Actor *wearer) {
	engine.gui->message(TCODColor::cyan, "Left-click an enemy to confuse it,\nor right-click to cancel.");
	int x,y;
	if (! engine.pickATile(&x,&y,range)) {
		return false;
	}

	Actor *actor=engine.getActor(x,y);
	if (! actor ) {
		return false;
	}
	// confuse the monster for <nbTurns> turns
	Ai *confusedAi=new ConfusedMonsterAi( nbTurns, actor->ai );
	actor->ai = confusedAi;
	engine.gui->message(TCODColor::lightGreen,"You've hacked the %s,\nit begins to move erratically!",
		actor->name);
	return Pickable::use(owner,wearer);
}

Overload::Overload(float range, float damage)
	: StaticBolt(range,damage) {		
}

bool Overload::use(Actor *owner, Actor *wearer) {
	engine.gui->message(TCODColor::cyan, "Left-click a target tile for the overload,\nor right-click to cancel.");
	int x,y;
	if (! engine.pickATile(&x,&y)) {
		return false;
	}
	// burn everything in <range> (including player)
	engine.gui->message(TCODColor::orange,"You overload everything within %g tiles!",range);
	for (Actor **iterator=engine.actors.begin();
	    iterator != engine.actors.end(); iterator++) {
		Actor *actor=*iterator;
		if ( actor->destructible && !actor->destructible->isDead()
			&& actor->getDistance(x,y) <= range) {
			engine.gui->message(TCODColor::orange,"The %s gets shocked for %g damage.",
				actor->name,damage);
			actor->destructible->takeDamage(actor,damage);
		}
	}
	return Pickable::use(owner,wearer);
}

